#include <iostream>
#include <pthread.h>
#include <cstring>
#include <unistd.h>

using namespace std;

int ticket = 10000;

class TData
{
public:
    TData(const string& name, pthread_mutex_t* mutex):_name(name), _pmutex(mutex)
    {}
    ~TData()
    {}
public:
    string _name;
    pthread_mutex_t* _pmutex;
};

void* thream_Routine(void* args)
{
    TData* td = static_cast<TData*>(args);
    while (true)
    {
        pthread_mutex_lock(td->_pmutex);
        if (ticket > 0)
        {
            usleep(2000);
            cout << td->_name << " get a ticket: " << ticket-- << endl; 
            pthread_mutex_unlock(td->_pmutex);
        }
        else
        {
            pthread_mutex_unlock(td->_pmutex);
            break;
        }

        usleep(1000);
    }
}

int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);
    pthread_t t[4];
    for (int i = 0; i < 4; ++i)
    {
        char* tname = new char[64];
        snprintf(tname, 64, "thread-%d", i+1);
        TData* td = new TData(tname, &mutex);
        pthread_create(&t[i], nullptr, thream_Routine, td);
    }

    for (int i = 0; i < 4; ++i)
    {
        pthread_join(t[i], nullptr);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}

// void* thread_Routine(void* args)
// {
//     string name = static_cast<const char*>(args);
    
//     int cnt = 5;
//     while (cnt)
//     {
//         cout << name << ": " << cnt-- << endl;
//         sleep(1);
//     }
//     pthread_exit(nullptr);
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, thread_Routine, (void*)"thread 1");
//     pthread_detach(tid);
//     int n = pthread_join(tid, nullptr);
//     if (n != 0)
//     {
//         cerr << "error: " << n << ":" << strerror(n) << endl;
//     }
//     sleep(10);
//     return 0;
// }